当DP遇见Py(四) -- 代理模式

目录
  1. 定义:
  2. 类图:
  3. 类型:结构型
  4. 实例:
    1. C++ 实现
    2. Python 实现
    3. Pythonic 实现
  5. Tips:

定义:

为其它对象提供一种代理以控制对这个对象的访问。

类图:

类型:结构型

实例:

给“小菜”一件一件穿衣服

C++ 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <string>
using namespace std;

class SchoolGirl
{
public:
string name;
};


class IGiveGift
{
public:
virtual void giveDolls()=0;
virtual void giveFlowers()=0;
};

class Pursuit:public IGiveGift
{
private:
SchoolGirl mm;
public:
Pursuit(SchoolGirl m)
{
mm=m;
}
void giveDolls()
{

cout<<mm.name<<" 送你洋娃娃"<<endl;
}
void giveFlowers()
{

cout<<mm.name<<" 送你鲜花"<<endl;
}
};

class Proxy:public IGiveGift
{
private:
Pursuit gg;
public:
Proxy(SchoolGirl mm):gg(mm)
{
}
void giveDolls()
{

gg.giveDolls();
}
void giveFlowers()
{

gg.giveFlowers();
}
};

int main()
{

SchoolGirl lijiaojiao;
lijiaojiao.name="李娇娇";
Pursuit zhuojiayi(lijiaojiao);
Proxy daili(lijiaojiao);

daili.giveDolls();
return 0;
}

Python 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# -*- coding=utf-8 -*-

class SchoolGirl:
def __init__(self, name):
self.name = name

class IGiveGift():
def giveDolls(self):
raise NotImplementedError()

def giveFlowers(self):
raise NotImplementedError()

class Pursuit(IGiveGift):
def __init__(self, m):
self.mm = m

def giveDolls(self):
print '%s 送你洋娃娃' % self.mm.name

def giveFlowers(self):
print '%s 送你鲜花' % self.mm.name

class Proxy(IGiveGift):
def __init__(self, mm):
self.gg = Pursuit(mm)

def giveDolls(self):
self.gg.giveDolls()

def giveFlowers(self):
self.gg.giveFlowers()

if __name__ == '__main__':
lijiaojiao = SchoolGirl('李娇娇')
daili = Proxy(lijiaojiao)
daili.giveDolls()
daili.giveFlowers()

Pythonic 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# -*- coding=utf-8 -*-

class SchoolGirl:
def __init__(self, name):
self.name = name

class Pursuit:
def __init__(self, m):
self.mm = m

def giveDolls(self):
print '%s 送你洋娃娃' % self.mm.name

def giveFlowers(self):
print '%s 送你鲜花' % self.mm.name

class Proxy():
def __init__(self, mm):
self.gg = Pursuit(mm)

def __getattr__(self, name):
return getattr(self.gg, name)

if __name__ == '__main__':
lijiaojiao = SchoolGirl('李娇娇')
daili = Proxy(lijiaojiao)
daili.giveDolls()
daili.giveFlowers()

Tips:

  • Python中的委派机制(delegation)使得Proxy的实现可以非常的简洁优美。如上所示,利用__getattr__,使得程序具有完整的通用性(generic)。这是动态语言特有的优势,详见Python的自省
  • __getattr__方法。当尝试调用一个不存在的方法时,Python会默认调用__getattr__。如,当调用daili.giveDolls()时,对象daili中并不存在giveDolls()这个方法,Python解释器就是去调用__getattr__方法。在__getattr__方法中,我们通过getattr内置函数来调用被代理对象,即self.gg的同名方法,来实现代理。
  • 魔术方法。 什么是魔术方法?它们是Python中的一些特殊方法,名字是以双下划线开始和结束,这些方法和类中的其他方法没有什么不同,只是在某些情况下类对象会自动调用这些特殊的方法。如,上所述的__getattr__方法和__init__方法(在对象初始化是调用)。魔术方法是Python面向对象的一切,想要弄清楚Python的面向对象是怎么来的,那就得好好研究Python的魔术方法。

PythonProxy实现就是这么简单。好用就是这么任性!

评论